package thesis;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Scanner;

import de.bwaldvogel.liblinear.InvalidInputDataException;
import de.bwaldvogel.liblinear.Predict;
import de.bwaldvogel.liblinear.Train;

public class Thesis {

	/**
	 * @param args
	 * @throws InvalidInputDataException 
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException, InvalidInputDataException {
		//label of classes
		ArrayList<String> label = new ArrayList<String>();
		label.add("1");
		label.add("2");
		label.add("3");
		label.add("4");
		label.add("5");
		
		//number of models
		ArrayList<String> model = new ArrayList<String>();
		for(int i = 0; i < label.size() - 1; i++){
			for(int j = i + 1; j < label.size(); j++){
				model.add((i + 1) + "_" + (j + 1));
			}
		}
		
		//array of original file to array to check accuracy 
		ArrayList<String> accuracyTrain = new ArrayList<String>();
		//array of classified file to array to check accuracy 
		ArrayList<String> accuracyTest = new ArrayList<String>();
		
		for(int i = 0; i < model.size(); i++){
			System.out.println(model.get(i));
		}
		
		String fileTestName = "1_2.test"; //test file which contains 1 or a lot of test file in LibSVM format
		String modelFile = null;
		String outputFile = null;
		
		//read file contains 1 or a lot of test file in LibSVM format
		ArrayList<String> fileNames = new ArrayList<String>();
		System.out.println(readArrayFile(fileTestName));
		fileNames.addAll(readArrayFile(fileTestName));

		ArrayList<String> realFilenames = new ArrayList<String>(); //array contain only 1 test in each file
		
		//write fileTestName to multi-file which contain only 1 test in each file
		for(int i = 0; i < fileNames.size(); i++){
			String[] singleFilenames = fileTestName.split("\\.");
			String singleFilename = singleFilenames[0] + "_" + (i + 1) + "." + singleFilenames[1];
			realFilenames.add(singleFilename);
			writeFile(singleFilename, fileNames.get(i));
			
			//add label of original file to array to check accuracy 
			if(fileNames.get(i).contains(" ")){
				accuracyTrain.add(fileNames.get(i).substring(0, fileNames.get(i).indexOf(" ")));
			} else {
				accuracyTrain.add(fileNames.get(i));
			}			
		}		
		
		
		//predict
		for(int i = 0; i < 10; i++){   //i < fileNames.size()
			String[] predictArg = new String[3]; 
			String testFileArg = "";
			String modelFileArg = "";
			String outFileArg = "";
			String beforeOutputFile = "";
			
			//default 1st & 2nd labels, start from 3rd label 
			for(int j = 1; j < label.size(); j++){
				if(j == 1){
					testFileArg = realFilenames.get(i);
					modelFileArg = "1_2.train.model";
					outFileArg = realFilenames.get(i).split("\\.")[0] + "_1_2.out";
					beforeOutputFile = outFileArg;
					
					predictArg[0] = testFileArg;
					predictArg[1] = modelFileArg;
					predictArg[2] = outFileArg;
					
//					System.out.println("predictArg: " + predictArg);
					
					Predict predict = new Predict();
			    	predict.main(predictArg);
				} else {
					//add label of output file to array to check accuracy 
					if(j == label.size() - 1){
						accuracyTest.add(getModel(beforeOutputFile));
					}
					
					testFileArg = realFilenames.get(i);
					modelFileArg = getModel(beforeOutputFile) + "_" + (j+1)  + ".train.model";
					System.out.println("modelFileArg: " + modelFileArg);
					outFileArg = realFilenames.get(i).split("\\.")[0] + "_" + getModel(beforeOutputFile) + "_" + (j+1) + ".out";
					System.out.println("beforeOutputFile: " + beforeOutputFile);
					System.out.println("outFileArg: " + outFileArg);
					beforeOutputFile = outFileArg;					
					
					predictArg[0] = testFileArg;
					predictArg[1] = modelFileArg;
					predictArg[2] = outFileArg;
					
					System.out.println("predictArg: " + predictArg);
					
					Predict predict = new Predict();
			    	predict.main(predictArg);
				}
			}
		}
		System.out.println("accuracyTrain.size(): " + accuracyTrain.size());
		System.out.println("accuracyTest.size(): " + accuracyTest.size());
		double accuracy = 0;
		int countAccuracy = 0;
//		if(accuracyTest.size() == accuracyTrain.size()){
			for(int i = 0; i < accuracyTest.size(); i++){
				System.out.println("accuracyTrain +  accuracyTest: " + accuracyTrain.get(i) + "+" + accuracyTest.get(i));
				if(accuracyTrain.get(i).equals(accuracyTest.get(i))){
					countAccuracy++;
				}
			}
			accuracy = countAccuracy/accuracyTest.size();
			System.out.println("countAccuracy: " + countAccuracy);
			System.out.println("Do chinh xac: " + accuracy);
//		}


//		System.out.println("Nhap thong so: ");
//		
//		BufferedReader buf = new BufferedReader (new InputStreamReader (System.in));
//		String line = buf.readLine ();
//		
//    	String input[] = line.split(" ");
//    	System.out.println(line);
//    	
//    	Predict predict = new Predict();
//    	predict.main(input);

	}
	
	// read before oue file to get current label, then add next label to get
	// exactly 2 label which is need to be classify
	static String getModel(String testFileName){
		String temp = "";
		try (BufferedReader br = new BufferedReader(new FileReader(testFileName))) {
			String sCurrentLine;
			while ((sCurrentLine = br.readLine()) != null) {
				temp += sCurrentLine;
				temp = temp.substring(0,1);
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("Label: " + temp);

		return temp;
	}

	static String readFile(String fileName) {
		String temp = "";
		try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
			String sCurrentLine;
			while ((sCurrentLine = br.readLine()) != null) {
				temp += sCurrentLine + "\n";
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return temp;
	}
	
	static void writeFile(String fileName, String writeString) {
		try {
			File fileDir = new File(fileName);
			BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileDir), "UTF8"));
			
			out.append(writeString);
			
			out.flush();
			out.close();
		} catch (UnsupportedEncodingException e) {
			System.out.println(e.getMessage());
		} catch (IOException e) {
			System.out.println(e.getMessage());
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	static ArrayList<String> readArrayFile(String fileName) {
		ArrayList<String> temp = new ArrayList<String>();
		try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
			String sCurrentLine;
			while ((sCurrentLine = br.readLine()) != null) {
				temp.add(sCurrentLine);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return temp;
	}
}
